<!--
*@Author: QWP
*@Description: 多人处理
*@Date: 2024-08-14 13:43:14
-->
<template>
  <a-layout class="s-bg-white">
    <u-form :model="form"
      :elements="fromEls">
      <template #reamrk>
        <span style="color: darkorange">1、设置或修改多人处理人规则后，需要保存发布才可生效</span> <br>
        <span style="color: darkorange">2、多人处理页签中未选择集合，且设置已处理人页签中未选择角色人员信息，则由上一步审核人员自行选择审核人员</span> <br>
        <span style="color: darkorange"><b>3、nrOfInstances：实例总数nrOfActiveInstances：当前活动（即尚未完成）实例的数量。对于顺序多实例，这将始终为1。nrOfCompletedInstances：已完成实例的数量。</b></span>
      </template>
    </u-form>
  </a-layout>
</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted, onUnmounted, h, nextTick, watch, toRaw } from 'vue' 
import { useTaskRuleStore, useLoginStore } from '@/store'
import { storeToRefs } from 'pinia'
import { useRoute, useRouter } from 'vue-router'
import { Button } from 'ant-design-vue'
import { cloneDeep } from 'lodash'
import { evectionUserTree } from '@/service/administration/travel'
import * as roleApi from '@/service/system/role'
import * as userApi from '@/service/system/user'
import { useDisTreeParent } from '@/hooks/useTree'
import { bpmnEventBus } from '@/util/eventBus'
import { numberC } from '@/util/common'

const props = defineProps<{
  businessObject: object,
  type: string,
  taskModeler:object,
  muiElement:object
}>()

onMounted(() => {
  // 处理人页签设置了处理人，则清除多人处理的数据
  bpmnEventBus.on('clearMoreUser', (element) => {
    form.value.loopCharacteristics = 'Null'

    changeLoopCharacteristicsType('Null', element)
    clearObj()
    updateCollection([], element, true)

    // 清除该节点多人处理的数据
    let collectionMultiple = JSON.parse(sessionStorage.getItem('collectionMultiple') || '{}')
    for(let key in collectionMultiple) {
      if(key.includes(element.id)) {
        delete collectionMultiple[key]
      }
    }
    sessionStorage.setItem('collectionMultiple', JSON.stringify(collectionMultiple))
  })
})

const multiLoopInstance = ref()
const defaultLoopInstanceForm = {
  completionCondition: "",
  loopCardinality: "",
  extensionElements: [],
  asyncAfter: false,
  asyncBefore: false,
  exclusive: false
}

const { userInfo } = storeToRefs(useLoginStore())

const baseData = reactive({
  rules: [
    { label: '并行多重事件', value: 'ParallelMultiInstance' },
    { label: '顺序多重事件', value: 'SequentialMultiInstance' },
    { label: '无', value: 'Null' },
  ],
  roles: [],
  users: [],
})
const form = ref({})
const formItemProps = { labelWidth: '100px', wrapCol: 24, required: true }
const fromEls = reactive([
  { label: '处理人规则', col: { span: 24 }, key: 'loopCharacteristics', element: 'select', formItemProps,
    componentProps: { 
      options: baseData.rules,
      onChange: (e) => {
        changeLoopCharacteristicsType(e)
        clearObj()
        updateCollection([])
        bpmnEventBus.emit('clearDealUser', e, props.muiElement)
      }
    }
  },
  { label: '循环基数', key: 'loopCardinality', element: 'input', formItemProps: { ...formItemProps, required: false},  
    col: { span: computed(() => form.value.loopCharacteristics != 'Null' ? 24 : 0) }, 
    componentProps: {
      disabled: true,
      onChange: function(e) {
        updateLoopCardinality(e.target.value)
      }
    }
  }, 
  { label: '集合', key: 'collection', element: 'selRoleUserTree', formItemProps: { ...formItemProps, required: false},  
    col: { span: computed(() => form.value.loopCharacteristics != 'Null' ? 24 : 0) }, 
    componentProps: { 
      extraData: computed(() => baseData.roles),
      fieldNames: { label: 'name', value: 'keyid' },
      multiple: true,
      disabled: true,
      isLoadData: false,
      class: 'f-normal-disable',
      checkStrictly: true,
      parent: { key: 'roleName', valueKey: 'fkparentid', parentTLable: '角色名称' },
      onSubmit: function(keys, data,) {
        updateCollection(keys)
      }
    },
  },
  { label: '元素变量', key: 'elementVariable', element: 'input', formItemProps,  
    col: { span: computed(() => form.value.loopCharacteristics != 'Null' ? 24 : 0) }, 
    componentProps: {
      disabled: true,
      onChange: function(e) {
        updateLoopBase(e.target.value)
      }
    }
  },
  { label: '完成条件', key: 'completionCondition', element: 'input', formItemProps,
    col: { span: computed(() => form.value.loopCharacteristics != 'Null' ? 24 : 0) }, 
    componentProps: {
      onChange: function(e) {
        updateLoopCondition(e.target.value)
      }
    }
  },
  { label: '设置说明', col: { span: 24 }, key: 'reamrk', element: 'slot', formItemProps}
])

const clearObj = () => {
  ['loopCardinality', 'collection', 'elementVariable', 'completionCondition'].forEach(key => {
    if(key == 'collection') {
      form.value[key] = []
    } else {
      form.value[key] = ''
    }
  })
}

watch(() => props.businessObject, () => {
  getRoles()
  getElementLoop(props.businessObject)
}, { immediate: true })

// 回显
function getElementLoop(businessObject) {
  businessObject = cloneDeep(props.muiElement.businessObject);
  // 处理人规则 - 无
  if (!businessObject.loopCharacteristics) {
    form.value = {};
    form.value.loopCharacteristics = "Null";
    return;
  }
  // 配置循环
  if (businessObject.loopCharacteristics.$type === "bpmn:StandardLoopCharacteristics") {
    form.value = {};
    form.value.loopCharacteristics = "StandardLoop";
    return;
  }

  // 处理人规则 - 顺序
  if (businessObject.loopCharacteristics.isSequential) {
    form.value.loopCharacteristics = "SequentialMultiInstance";
  } 
  // 处理人规则 - 并行
  else {
    form.value.loopCharacteristics = "ParallelMultiInstance";
  }
  let collectionMultiple = JSON.parse(sessionStorage.getItem('collectionMultiple') || '{}')
  let collection = [];
  if(collectionMultiple[props.muiElement.id +'_byMulit']) {
    collection = collectionMultiple[props.muiElement.id +'_byMulit'] || []
  }

  // 合并配置
  form.value = {
    ...form.value,
    ...defaultLoopInstanceForm,
    ...businessObject.loopCharacteristics,
    collection,
    completionCondition: businessObject.loopCharacteristics?.completionCondition?.body ?? "",
    // loopCardinality: businessObject.loopCharacteristics?.loopCardinality?.body ?? ""
    loopCardinality: collection.length
  };
  
  // 保留当前元素 businessObject 上的 loopCharacteristics 实例
  multiLoopInstance.value = props.muiElement.businessObject.loopCharacteristics;
  // 更新表单
  if (
    businessObject.loopCharacteristics.extensionElements &&
    businessObject.loopCharacteristics.extensionElements.values &&
    businessObject.loopCharacteristics.extensionElements.values.length
  ) {
    form.value.timeCycle = businessObject.loopCharacteristics.extensionElements.values[0].body
  }
}

// 处理规则更新
function changeLoopCharacteristicsType(type, xmlEl?: any) {
  // form = { ...this.defaultLoopInstanceForm }; // 切换类型取消原表单配置
  const tmuiElement = toRaw(xmlEl ? xmlEl : props.muiElement)

  // 取消多实例配置
  if (type === "Null") {
    window.bpmnInstances.modeling.updateProperties(tmuiElement, { loopCharacteristics: null });
    form.value.elementVariable = ''
    return;
  }

  // 配置循环
  if (type === "StandardLoop") {
    const loopCharacteristicsObject = window.bpmnInstances.moddle.create("bpmn:StandardLoopCharacteristics");
    window.bpmnInstances.modeling.updateProperties(tmuiElement, {
      loopCharacteristics: loopCharacteristicsObject
    });
    multiLoopInstance.value = null;
    return;
  }

  // 时序
  if (type === "SequentialMultiInstance") {
    multiLoopInstance.value = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", {
      isSequential: true
    });
  } else {
    multiLoopInstance.value = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics");
  }

 try {
    window.bpmnInstances.modeling.updateProperties(tmuiElement, {
      loopCharacteristics: multiLoopInstance.value
    });
 } catch (error) {}
}

// 更新集合
function updateCollection(data, xmlEl?: any, isClear?: boolean = false) {
  const tData = (data || form.value.collection) || []
  const tmuiElement = toRaw(xmlEl ? xmlEl : props.muiElement)

  // 更新循环基数
  form.value.loopCardinality = tData.length;

  // 用于整个流程发布保存时，作为variablemap 的值
  bpmnEventBus.emit('collectionMultiple', { key: tmuiElement.id +'_byMulit', value: tData, clear: isClear })
  
  // 设置collection 变量
  multiLoopInstance.value = props.muiElement.businessObject.loopCharacteristics;
  if(multiLoopInstance.value) {
    try {
      window.bpmnInstances.modeling.updateModdleProperties(tmuiElement, multiLoopInstance.value, {
        collection: "${"+ tmuiElement.id +"_byMulit}" 
      });
    } catch (error) {}
  }

  try {
    updateLoopCardinality(tData.length.toString())
  } catch (error) {}

  // 设置元素变量
  form.value.elementVariable = form.value.loopCharacteristics == 'Null' ? '' : 'usr'
  try {
    updateLoopBase(form.value.elementVariable)
  } catch (error) {}

  // 完成条件
  try {
    form.value.completionCondition = form.value.loopCharacteristics == 'Null' ? '' : "${nrOfInstances == nrOfCompletedInstances}"
    updateLoopCondition(form.value.completionCondition)
  } catch (error) {}
}

// 循环基数
function updateLoopCardinality(cardinality) {
  if(!multiLoopInstance.value) {
    return
  }
  const tmuiElement = toRaw(props.muiElement)
  let loopCardinality = null;
  if (cardinality && cardinality.length) {
    loopCardinality = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { 
      body: cardinality == '0' ? '${'+ tmuiElement.id+'_byMulit_byNum}' : cardinality  
    });
  }
  window.bpmnInstances.modeling.updateModdleProperties(tmuiElement, multiLoopInstance.value, {
    loopCardinality: loopCardinality
  });
}

// 完成条件
function updateLoopCondition(condition) {
  if(!multiLoopInstance.value) {
    return
  }
  let completionCondition = null;
  if (condition && condition.length) {
    completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: condition });
  }
  window.bpmnInstances.modeling.updateModdleProperties(toRaw(props.muiElement), multiLoopInstance.value, {
    completionCondition
  });
}

// 重试周期
function updateLoopTimeCycle(timeCycle) {
  if(!multiLoopInstance.value) {
    return
  }
  const extensionElements = window.bpmnInstances.moddle.create("bpmn:ExtensionElements", {
    values: [
      window.bpmnInstances.moddle.create(`${this.prefix}:FailedJobRetryTimeCycle`, {
        body: timeCycle
      })
    ]
  });
  window.bpmnInstances.modeling.updateModdleProperties(toRaw(props.muiElement), multiLoopInstance.value, {
    extensionElements
  });
}

// 直接更新的基础信息
function updateLoopBase() {
  if(!multiLoopInstance.value) {
    return
  }
  // 元素变量
  window.bpmnInstances.modeling.updateModdleProperties(toRaw(props.muiElement), multiLoopInstance.value, {
    elementVariable: form.value.elementVariable || null
  });
}

// 各异步状态
function updateLoopAsync(key) {
  if(!multiLoopInstance.value) {
    return
  }
  const { asyncBefore, asyncAfter } = form.value;
  let asyncAttr = Object.create(null);
  if (!asyncBefore && !asyncAfter) {
    form.value.exclusive = false
    asyncAttr = { asyncBefore: false, asyncAfter: false, exclusive: false, extensionElements: null };
  } else {
    asyncAttr[key] = form.value[key];
  }
  window.bpmnInstances.modeling.updateModdleProperties(toRaw(props.muiElement), multiLoopInstance.value, asyncAttr);
}

// 获取角色信息数据
function getRoles() {
  if(baseData.roles.length != 0) {
    return
  }
  userApi.roleuserselectdata().then(res => {
    if(res.code == 0) {
      baseData.roles = res.data || [];
    }
  })
}

onUnmounted(() => {
  bpmnEventBus.off('clearDealUser')
  bpmnEventBus.off('clearMoreUser')
})
</script>

<style lang='scss' scoped>
</style>